home *** CD-ROM | disk | FTP | other *** search
/ Multimedia Jumpstart / Multimedia Microsoft Jumpstart Version 1.1a (Microsoft).BIN / develpmt / drivers / mscdex / hitachi / macros.mac < prev    next >
Encoding:
Text File  |  1990-10-15  |  20.7 KB  |  1,016 lines

  1.     page    ,132
  2. ;-----------------------------Module-Header-----------------------------;
  3. ; Module Name:    MACROS.MAC
  4. ;
  5. ; This file contains macros definitions for all display drivers to use.
  6. ;
  7. ; Created: 06-Jan-1987
  8. ; Author:  Walt Moore [waltm]
  9. ;
  10. ; Copyright (c) 1987 Microsoft Corporation
  11. ;
  12. ; Exported Functions:    none
  13. ;
  14. ; Public Functions:    none
  15. ;
  16. ; Public Data:        none
  17. ;
  18. ; General Description:
  19. ;
  20. ;    Two text equates are given as short hand for WORD PTR
  21. ;    and BYTE PTR.
  22. ;
  23. ;    A Macro is defined for performing 16-bit output on machines
  24. ;    which cannot correctly do so.
  25. ;
  26. ;    The macro which is invoked by CMACROS for private stack
  27. ;    checking is defined.
  28. ;
  29. ; Restrictions:
  30. ;    The use of the ?CHKSTKPROC macro requires it to be defined
  31. ;    before CMACROS is included.  If CMACROS is included before
  32. ;    the include file, a ?CHKSTKPROC macro should be defined
  33. ;    with a null macro body.  This macro will then redefine the
  34. ;    earlier macro.
  35. ;
  36. ;    The out16 macro is intended as documentation for anyone
  37. ;    converting a driver to a machine which cannot do 16-bit
  38. ;    outputs correctly.  There is no guarantee that any code
  39. ;    will have been tested (only one machine is known to have
  40. ;    the problem).
  41. ;
  42. ;-----------------------------------------------------------------------;
  43.  
  44.  
  45.  
  46.  
  47. ;    The following two equates are just used as shorthand
  48. ;    for the "word ptr" and "byte ptr" overrides.
  49.  
  50. fptr    equ    fword ptr
  51. wptr    equ    word  ptr
  52. bptr    equ     byte  ptr
  53.  
  54. ; The following structure should be used to access high and low
  55. ; words of a DWORD.  This means that "word ptr foo[2]" -> "foo.hi".
  56.  
  57. LONG    struc
  58. lo      dw      ?
  59. hi      dw      ?
  60. LONG    ends
  61.  
  62. FARPOINTER      struc
  63. off     dw      ?
  64. sel     dw      ?
  65. FARPOINTER      ends
  66.  
  67. FPOINTER        struc
  68. foff    dd      ?
  69. fsel    dw      ?
  70. FPOINTER        ends
  71.  
  72. ;---------------------------------Macro---------------------------------;
  73. ; out16
  74. ;
  75. ; out16 is a macro used wherever any 16-bit output is performed.
  76. ; The macro is intended to serve as documentation for those machines
  77. ; which do not perform 16-bit outputs correctly (where correctly is
  78. ; defined as the way the IBM AT does it).
  79. ;
  80. ; usage
  81. ;
  82. ;     out16   d,a
  83. ;
  84. ; where
  85. ;
  86. ;     d   -   I/O address register. Included as documentation
  87. ;          only.  Must always be DX (lower case).
  88. ;
  89. ;     a   -   Register to output.  Included as documentation
  90. ;          only.  Must always be AX (lower case).
  91. ;
  92. ; Entry:
  93. ;    AX    = data to output
  94. ;    DX    = I/O port address
  95. ; Returns:
  96. ;    none
  97. ; Error Returns:
  98. ;    none
  99. ; Registers Destroyed:
  100. ;    FLAGS
  101. ; Registers Preserved:
  102. ;    AX,BX,CX,DX,SI,DI,BP,DS,ES
  103. ; Calls:
  104. ;       none
  105. ; History:
  106. ;    Fri 16-Jan-1987 16:49:03 -by-  Walt Moore [waltm]
  107. ;    Initial version
  108. ;-----------------------------------------------------------------------;
  109.  
  110.  
  111. ifndef    IO8                ;;If normal 16 bit outputs
  112.   out16   equ      out
  113. else                    ;;If 8-bit outputs
  114.   out16 macro d,a
  115.     ifdif <a>,<ax>
  116.     %out out16 - invalid register, must be ax
  117.     .err
  118.     endif
  119.     ifdif    <d>,<dx>
  120.     %out    out16 - invalid register, must be dx
  121.     .err
  122.     endif
  123.     ifdif <is>,<cli>        ;;  If interrupts not off
  124.     cli                ;;    then turn them off
  125.     endif                ;;
  126.     out    dx,al            ;;  Output LSB portion
  127.     inc    dx            ;;  --> next address
  128.     xchg    al,ah            ;;  Get MSB of output value
  129.     out    dx,al            ;;  Output MSB portion
  130.     ifdif <ie>,<cli>        ;;  If not explicitly told to leave
  131.     sti                ;;    interrupts off, turn them on
  132.     endif                ;;
  133.     ifdif <rd>,<dont_save_DL>    ;;  If not explicitly told to trash DX,
  134.     dec    dx            ;;    restore it.
  135.     xchg    al,ah
  136.     endif
  137.     endm
  138. endif
  139.  
  140.  
  141.  
  142. ;---------------------------------Macro---------------------------------;
  143. ; ?CHKSTKPROC
  144. ;
  145. ; Private Stack Checking Macro
  146. ;
  147. ; ?CHKSTKPROC will be invoked by the CMACROS for any procedure
  148. ; with local variables if both ?CHKSTK and ?CHKSTKPROC were
  149. ; defined prior to including the CMACROS.
  150. ;
  151. ; The macro has one parameter, which is the number of bytes
  152. ; to allocate, which is supplied by the CMACROS.
  153. ;
  154. ; The usage of this macro is defined by the CMACROS.  There is no
  155. ; user control over the macro.    Register usage will be as defined
  156. ; by the routine my_check_stack.
  157. ;
  158. ; Calls:
  159. ;    my_check_stack
  160. ; History:
  161. ;    Fri 16-Jan-1987 16:49:03 -by-  Walt Moore [waltm]
  162. ;    Initial version
  163. ;-----------------------------------------------------------------------;
  164.  
  165.  
  166. ifdef    ?CHKSTK             ;;Only define macro if
  167. ifdef    ?CHKSTKPROC            ;;  private stack checking
  168. ifndef    ?CHKSTKNAME            ;;If user name differs from default
  169. extrn    my_check_stack:near        ;;Procedure to do the checking
  170. endif
  171. ?CHKSTKPROC macro s            ;;Actual macro text
  172.     mov    ax,s            ;;my_check_stack takes requested space
  173. ifdef    ?CHKSTKNAME
  174.     ?CHKSTKNAME
  175. else
  176.     call    my_check_stack        ;;  in AX
  177. endif
  178. endm
  179. endif
  180. endif
  181.  
  182.  
  183.  
  184. ;-----------------------------------------------------------------------;
  185. ; odd    --- macro for odd alignment, counterpart for masm's "even".
  186. ;
  187. ; Arguments:
  188. ;    none
  189. ; Returns:
  190. ;    nothing
  191. ; Alters:
  192. ;    nothing
  193. ; Calls:
  194. ;    nothing
  195. ; History:
  196. ;
  197. ;  Sun Mar 01, 1987 07:48:01p    -by-    Wesley O. Rupel   [wesleyr]
  198. ; Wrote it!
  199. ;-----------------------------------------------------------------------;
  200.  
  201.  
  202. odd    macro
  203.     ife (offset $) AND 1
  204.     nop
  205.     endif
  206.     endm
  207.  
  208.  
  209.  
  210. ;-----------------------------------------------------------------------;
  211. ; pushem
  212. ; popem
  213. ;
  214. ; Allows giving a list of registers to push/pop on a single line.
  215. ; Also allows easy verificaton that pushes and pops are balanced
  216. ; because arguements are given in the same order:
  217. ;
  218. ;    pushem    ax,bx,cx   goes with
  219. ;    popem    ax,bx,cx
  220. ;
  221. ; Arguments:
  222. ;    registers to push/pop
  223. ; Returns:
  224. ;    nothing
  225. ; Alters:
  226. ;    nothing
  227. ; Calls:
  228. ;    nothing
  229. ; History:
  230. ;
  231. ;  Mon Mar 09, 1987 06:12:32p    -by-    Wesley O. Rupel   [wesleyr]
  232. ; Wrote it!
  233. ;-----------------------------------------------------------------------;
  234.  
  235.  
  236. pushem    macro    r1,r2,r3,r4,r5,r6,r7,r8,r9,rA,rB,rC,rD,rE,rF,r10,r11,r12
  237.     irp    x,<r1,r2,r3,r4,r5,r6,r7,r8,r9,rA,rB,rC,rD,rE,rF,r10,r11,r12>
  238.     ifnb    <x>
  239.     push    x
  240.     endif
  241.     endm
  242.     endm
  243.  
  244. popem    macro    r1,r2,r3,r4,r5,r6,r7,r8,r9,rA,rB,rC,rD,rE,rF,r10,r11,r12
  245.     irp    x,<r12,r11,r10,rF,rE,rD,rC,rB,rA,r9,r8,r7,r6,r5,r4,r3,r2,r1>
  246.     ifnb    <x>
  247.     pop    x
  248.     endif
  249.     endm
  250.     endm
  251.  
  252.  
  253.  
  254. ;-----------------------------------------------------------------------;
  255. ; smov
  256. ;
  257. ; smove moves the contents of one segment register into another
  258. ; segment register.
  259. ;
  260. ; usage
  261. ;
  262. ;    smov    x,y
  263. ;
  264. ; where
  265. ;
  266. ;    x is the destination register
  267. ;    y is the source register
  268. ;
  269. ; Arguments:
  270. ;    y is source segment register
  271. ; Returns:
  272. ;    x segment register = y segment register
  273. ; Alters:
  274. ;    x segment register
  275. ; Calls:
  276. ;    nothing
  277. ; History:
  278. ;
  279. ;  Mon Mar 09, 1987 06:12:32p    -by-    Wesley O. Rupel   [wesleyr]
  280. ; Wrote it!
  281. ;-----------------------------------------------------------------------;
  282.  
  283.  
  284. smov    macro    x,y
  285.     push    y
  286.     pop    x
  287.     endm
  288.  
  289.  
  290. ;-----------------------------------------------------------------------;
  291. ; jmps  - jump short
  292. ;
  293. ; does a shourt jump, (stupid masm!)
  294. ;
  295. ; usage
  296. ;       jmps    label       ==>     jmp short label
  297. ;
  298. ; where
  299. ;       label is the destination label
  300. ;
  301. ;-----------------------------------------------------------------------;
  302.  
  303. jmps    macro   there
  304.         jmp     short there
  305.     endm
  306.  
  307.  
  308. ;--------------------------------------------------------------------------;
  309. ; abs_ax
  310. ;    takes absolute value of AX
  311. ; Entry:
  312. ;    AX    = integer
  313. ; Returns:
  314. ;    AX    = abs(AX)
  315. ; Error Returns:
  316. ;    none
  317. ; Registers Destroyed:
  318. ;    DX,FLAGS
  319. ; Registers Preserved:
  320. ;    BX,CX,SI,DI,DS,ES,BP
  321. ; Calls:
  322. ;    none
  323. ; History:
  324. ;  Thu Mar 05, 1987 06:15:46p    -by-  Tony Pisculli    [tonyp]
  325. ; wrote it
  326. ;--------------------------------------------------------------------------;
  327.  
  328.  
  329. abs_ax    macro
  330.     cwd
  331.     xor    ax,dx
  332.     sub    ax,dx
  333.     endm
  334.  
  335.  
  336.  
  337. ;--------------------------------------------------------------------------;
  338. ; min_ax
  339. ;    returns min of AX and REG
  340. ; Entry:
  341. ;    AX    = integer
  342. ;    REG    = general purpose register containing an integer
  343. ; Returns:
  344. ;    AX    = min(AX,REG)
  345. ; Error Returns:
  346. ;    none
  347. ; Registers Destroyed:
  348. ;    DX,FLAGS
  349. ; Registers Preserved:
  350. ;    BX,CX,SI,DI,DS,ES,BP
  351. ; Calls:
  352. ;    none
  353. ; History:
  354. ;  Sat Mar 07, 1987 08:39:04p    -by-  Tony Pisculli    [tonyp]
  355. ; wrote it
  356. ;--------------------------------------------------------------------------;
  357.  
  358.  
  359. min_ax  macro   REG
  360. ifdif <REG>,<0>
  361.         sub     ax,REG
  362. endif
  363.     cwd
  364.     and    ax,dx
  365. ifdif <REG>,<0>
  366.         add     ax,REG
  367. endif
  368.     endm
  369.  
  370.  
  371.  
  372. ;--------------------------------------------------------------------------;
  373. ; max_ax
  374. ;    returns max of AX and REG
  375. ; Entry:
  376. ;    AX    = integer
  377. ;    REG    = general purpose register containing an integer
  378. ; Returns:
  379. ;    AX    = max(AX, REG)
  380. ; Error Returns:
  381. ;    none
  382. ; Registers Destroyed:
  383. ;    DX,FLAGS
  384. ; Registers Preserved:
  385. ;    BX,CX,SI,DI,DS,ES,BP
  386. ; Calls:
  387. ;    none
  388. ; History:
  389. ;  Sat Mar 07, 1987 08:41:38p    -by-  Tony Pisculli    [tonyp]
  390. ; wrote it
  391. ;--------------------------------------------------------------------------;
  392.  
  393.  
  394. max_ax  macro   REG
  395. ifdif <REG>,<0>
  396.         sub     ax,REG
  397. endif
  398.     cwd
  399.     not    dx
  400.         and     ax,dx
  401. ifdif <REG>,<0>
  402.         add     ax,REG
  403. endif
  404.     endm
  405.  
  406.  
  407.  
  408. ;    The following equates are used for defining the target
  409. ;    processor to the shift macros.
  410.  
  411.  
  412. GENERIC    equ    0
  413.  
  414.  CPU    equ     GENERIC
  415. ;CPU    equ    88
  416. ;CPU    equ    86
  417. ;CPU    equ    186
  418. ;CPU    equ     286
  419. ;CPU    equ    386
  420.  
  421.  
  422.  
  423. ;--------------------------------------------------------------------------;
  424. ; shiftl
  425. ;
  426. ; shiftl is used to implement the advanced shift left immediate
  427. ; (SHL dest,count) functionality of the 286 and 386.
  428. ;
  429. ; Entry:
  430. ;    DEST    = var to shift
  431. ;    COUNT    = number to shift by
  432. ; Returns:
  433. ;    DEST    = DEST shl COUNT
  434. ; Error Returns:
  435. ;    none
  436. ; Registers Destroyed:
  437. ;    none
  438. ; Registers Preserved:
  439. ;    all
  440. ; Calls:
  441. ;    none
  442. ; History:
  443. ;  Sat Mar 07, 1987 08:44:30p    -by-  Tony Pisculli    [tonyp]
  444. ; wrote it
  445. ;--------------------------------------------------------------------------;
  446.  
  447.  
  448. shiftl    macro    DEST,COUNT
  449. if (CPU eq 286) or (CPU eq 386)
  450.     shl    DEST,COUNT
  451. else
  452.     REPT    COUNT
  453.     shl    DEST,1
  454.     ENDM
  455. endif
  456.     endm
  457.  
  458.  
  459.  
  460. ;--------------------------------------------------------------------------;
  461. ; shiftr
  462. ;
  463. ; shiftr is used to implement the advanced shift right immediate
  464. ; (SHR dest,count) functionality of the 286 and 386.
  465. ;
  466. ; Entry:
  467. ;    DEST    = var to shift
  468. ;    COUNT    = number to shift by
  469. ; Returns:
  470. ;    DEST    = DEST shr COUNT
  471. ; Error Returns:
  472. ;    none
  473. ; Registers Destroyed:
  474. ;    none
  475. ; Registers Preserved:
  476. ;    all
  477. ; Calls:
  478. ;    none
  479. ; History:
  480. ;  Sat Mar 07, 1987 08:44:52p    -by-  Tony Pisculli    [tonyp]
  481. ; wrote it
  482. ;--------------------------------------------------------------------------;
  483.  
  484.  
  485. shiftr    macro    DEST,COUNT
  486. if (CPU eq 286) or (CPU eq 386)
  487.     shr    DEST,COUNT
  488. else
  489.     REPT    COUNT
  490.     shr    DEST,1
  491.     ENDM
  492. endif
  493.     endm
  494.  
  495.  
  496. ;--------------------------------------------------------------------------;
  497. ; rotcr, rotcl
  498. ; rotr, rotl
  499. ;
  500. ; Use just like you would rcr (or rcl, rol, ror) immediate in 286 specific
  501. ; code.  If the processor does not support the immediate count (>1 on 808[68])
  502. ; then the macro generates multiple rcr (...) by one statements.
  503. ;
  504. ; Entry:
  505. ;    DEST    = var to rotate
  506. ;    COUNT    = number to rotate by
  507. ; Returns:
  508. ;    DEST    = DEST shr COUNT
  509. ; Error Returns:
  510. ;    none
  511. ; Registers Destroyed:
  512. ;    none
  513. ; Registers Preserved:
  514. ;    all
  515. ; Calls:
  516. ;    none
  517. ; History:
  518. ;  Fri Apr 17, 1987 08:39:39p    -by-    Wesley O. Rupel      [wesleyr]
  519. ; added rotl and rotr
  520. ;
  521. ;  Sun Apr 12, 1987 07:34:37p    -by-    Wesley O. Rupel      [wesleyr]
  522. ; wrote it
  523. ;--------------------------------------------------------------------------;
  524.  
  525.  
  526. rotcr    macro    DEST,COUNT
  527. if (CPU eq 286) or (CPU eq 386)
  528.     rcr    DEST,COUNT
  529. else
  530.     REPT    COUNT
  531.     rcr    DEST,1
  532.     ENDM
  533. endif
  534.     endm
  535.  
  536. rotcl    macro    DEST,COUNT
  537. if (CPU eq 286) or (CPU eq 386)
  538.     rcl    DEST,COUNT
  539. else
  540.     REPT    COUNT
  541.     rcl    DEST,1
  542.     ENDM
  543. endif
  544.     endm
  545.  
  546.  
  547.  
  548. rotl    macro    DEST,COUNT
  549. if (CPU eq 286) or (CPU eq 386)
  550.     rol    DEST,COUNT
  551. else
  552.     REPT    COUNT
  553.     rol    DEST,1
  554.     ENDM
  555. endif
  556.     endm
  557.  
  558.  
  559. rotr    macro    DEST,COUNT
  560. if (CPU eq 286) or (CPU eq 386)
  561.     ror    DEST,COUNT
  562. else
  563.     REPT    COUNT
  564.     ror    DEST,1
  565.     ENDM
  566. endif
  567.     endm
  568.  
  569.  
  570. ;--------------------------------------------------------------------------;
  571. ; ashiftr
  572. ;
  573. ; ashiftr is used to implement the advanced shift arithmetic right immediate
  574. ; (SAR dest,count) functionality of the 286 and 386.
  575. ;
  576. ; Entry:
  577. ;    DEST    = var to shift
  578. ;    COUNT    = number to shift by
  579. ; Returns:
  580. ;    DEST    = DEST sar COUNT
  581. ; Error Returns:
  582. ;    none
  583. ; Registers Destroyed:
  584. ;    none
  585. ; Registers Preserved:
  586. ;    all
  587. ; Calls:
  588. ;    none
  589. ; History:
  590. ;  Sat Mar 07, 1987 08:45:06p    -by-  Tony Pisculli    [tonyp]
  591. ; wrote it
  592. ;--------------------------------------------------------------------------;
  593.  
  594.  
  595. ashiftr    macro    DEST,COUNT
  596. if (CPU eq 286) or (CPU eq 386)
  597.     sar    DEST,COUNT
  598. else
  599.     REPT    COUNT
  600.     sar    DEST,1
  601.     ENDM
  602. endif
  603.     endm
  604.  
  605.  
  606.  
  607. ;---------------------------------Macro---------------------------------;
  608. ; jmpnext
  609. ; jmpnext stop
  610. ;
  611. ; jmpnext is used in the generation of fall through chains.  It
  612. ; generates the opcode used to swallow the next two bytes of object
  613. ; code (cmp ax,immediate word), and performs error checking to
  614. ; ensure that only two bytes of object code exist between any
  615. ; use of jmpnext.
  616. ;
  617. ; The chain is terminated by use of an optional parameter to jmpnext.
  618. ; If this optional field is non-blank, the chain is terminated.
  619. ;
  620. ; usage
  621. ;
  622. ;    dog:
  623. ;          mov    al,34
  624. ;         jmpnext
  625. ;
  626. ;    foo:
  627. ;         mov     al,0
  628. ;         jmpnext
  629. ;
  630. ;    bar:
  631. ;         mov     al,1
  632. ;         jmpnext stop            ;End of the chain
  633. ;
  634. ; Entry:
  635. ;    none
  636. ; Returns:
  637. ;    none
  638. ; Error Returns:
  639. ;    none
  640. ; Registers Destroyed:
  641. ;    FLAGS
  642. ; Registers Preserved:
  643. ;    AX,BX,CX,DX,SI,DI,BP,DS,ES
  644. ; Calls:
  645. ;       none
  646. ; History:
  647. ;    Fri 13-Mar-1987 12:03:16 -by-  Walt Moore [waltm]
  648. ;    Initial version
  649. ;-----------------------------------------------------------------------;
  650.  
  651.  
  652. ??ji    =    0            ;;Initial index value
  653.  
  654. jmpnext macro e
  655. jn %??ji,%(??ji+1),e            ;;Set next label
  656. endm
  657.  
  658. jn macro i,j,e
  659. .sall
  660. ??ji&i:
  661. .xall
  662. ifb <e>                 ;;If not the end of the chain
  663.     db    03Dh            ;;cmp ax, next two bytes
  664. errn$    ??ji&j,+2            ;;next lable must be two bytes away
  665. endif
  666. ??ji=j                    ;;increment counter
  667. endm
  668.  
  669.  
  670.  
  671. ;---------------------------------Macro---------------------------------;
  672. ; missing_code
  673. ;
  674. ; missing_code is a macro which will display a message on the screen
  675. ; at assembly time.  It is used to flag code sequences which have not
  676. ; been completed.
  677. ;
  678. ; usage
  679. ;
  680. ;    missing_code    <text>
  681. ;
  682. ; Entry:
  683. ;    none
  684. ; Returns:
  685. ;    none
  686. ; Error Returns:
  687. ;    none
  688. ; Registers Destroyed:
  689. ;    none
  690. ; Registers Preserved:
  691. ;    ALL
  692. ; Calls:
  693. ;       none
  694. ; History:
  695. ;    Sun 22-Mar-1987 18:21:34 -by-  Walt Moore [waltm]
  696. ;    Initial version
  697. ;-----------------------------------------------------------------------;
  698.  
  699. missing_code    macro    x
  700.     if1
  701.     ??_out    <&! Missing Code &!  x>
  702.     endif
  703.     endm
  704.  
  705. ;---------------------------Macro---------------------------------------;
  706. ; LMHtoP
  707. ;
  708. ; Converts a Local Memory Handle to a local pointer.
  709. ;
  710. ; Entry:
  711. ;     reg1[,reg2]
  712. ; Returns:
  713. ;     reg1 = pointer
  714. ; Error Returns:
  715. ;     
  716. ; Registers Destroyed:
  717. ;     none
  718. ; History:
  719. ;  Mon Mar 23, 1987 06:54:26a  -by-  Charles Whitmer [chuckwh]
  720. ; Imported from GDI.
  721. ;-----------------------------------------------------------------------;
  722.  
  723. LMHtoP macro r1,r2        ;; Local Movable Handle to pointer
  724. ifnb <r2>
  725.     mov    r1,[r2]
  726. else
  727.     mov    r1,[r1]
  728. endif
  729. endm
  730.  
  731.  
  732. ;-------------------------Macro-----------------------------------------;
  733. ; WriteAux
  734. ;
  735. ; Writes some debugging info to the standard aux device.
  736. ;
  737. ; Entry:
  738. ;    none
  739. ; Returns:
  740. ;    none - string was output to aux
  741. ; History:
  742. ;   Wed Apr-05-1981 -by- Gary Maltzen, Preferred Solutions, Inc.
  743. ;   Changed to use TRACER.
  744. ;
  745. ;   Mon Jan-30-1989 -by- David Miller, Video Seven Inc.
  746. ;   Wrote it.
  747. ;
  748. ;-----------------------------------------------------------------------;
  749.  
  750. ifdef    DEBUG
  751.  
  752.     extrn   tracer : far
  753.  
  754. WriteAux    macro    text
  755.     local    over
  756.     call    tracer
  757.     jmp    short over
  758.     db    "&text&",13,10
  759. over    label    near
  760.         endm
  761.  
  762. else;    DEBUG
  763.  
  764. WriteAux    macro
  765.         endm
  766.  
  767. endif;    DEBUG
  768.  
  769. ;WriteAux    macro   dstr
  770. ;    local    WriteAuxStr,WriteAuxStrLen
  771. ;
  772. ;ifdef    DEBUG
  773. ;
  774. ;    jmp    @F
  775. ;
  776. ;WriteAuxStr    db  dstr,10,13
  777. ;WriteAuxStrLen    equ $-WriteAuxStr
  778. ;
  779. ;@@:
  780. ;    push    ax
  781. ;    push    bx
  782. ;    push    cx
  783. ;    push    dx
  784. ;    push    ds
  785. ;
  786. ;    mov    ax,cs            ;Get segment of string into ds
  787. ;    mov    ds,ax
  788. ;    lea    dx,WriteAuxStr
  789. ;    mov    cx,WriteAuxStrLen
  790. ;    mov    bx,0003h        ;standard aux device
  791. ;    mov    ah,040h         ;Write String
  792. ;    int    21h
  793. ;
  794. ;    pop    ds
  795. ;    pop    dx
  796. ;    pop    cx
  797. ;    pop    bx
  798. ;    pop    ax
  799. ;endif
  800. ;    endm
  801.  
  802. ;-------------------------Macro-----------------------------------------;
  803. ; ?_pub
  804. ;
  805. ; Conditionally generates debugging public symbol if PUBDEFS is defined.
  806. ;
  807. ; Entry:
  808. ;
  809. ; Returns:
  810. ;
  811. ; History:
  812. ;    Mon 13-Feb-1989  -by-  Gary Maltzen.
  813. ;    Wrote it.
  814. ;
  815. ;-----------------------------------------------------------------------;
  816.  
  817. ?_pub    macro    name
  818.     ifdef    PUBDEFS
  819.     public    name
  820.     endif
  821.     endm
  822.  
  823. ;-------------------------Macro-----------------------------------------;
  824. ; REPSTOSB Dst
  825. ;
  826. ; store <cx> copies of al at Dst, aliging destination on WORD writes
  827. ;
  828. ;   Dst         destination, must be of the form SEL:[di] (default is es:[di])
  829. ;
  830. ; Entry:
  831. ;   Dst         -> points to dest buffer
  832. ;   al          byte to write
  833. ;   cx          count bytes
  834. ;
  835. ; NOTE a dest segment other than ES is handled by generating a loop
  836. ; all other cases generate a rep mov
  837. ;
  838. ; NOTE this code assumes the direction flag is set to FORWARD
  839. ;
  840. ; Returns:
  841. ;
  842. ; History:
  843. ;       Sun 31-Jul-1989  -by-  ToddLa
  844. ;    Wrote it.
  845. ;
  846. ;-----------------------------------------------------------------------;
  847.  
  848. ?REPSTOSB macro Dst
  849.         local   l1
  850.         local   l2
  851.         local   l3
  852.  
  853.         mov     ah,al               ; make sure ah == al
  854. fesdi = 0
  855.  
  856. ifidni <Dst>,<es:[di]>
  857.     fesdi = 1
  858. endif
  859.  
  860. ifidni <Dst>,<es:[edi]>
  861.     fesdi = 1
  862. endif
  863.  
  864. if fesdi
  865. ;
  866. ;   This is the easy case, we can use stos
  867. ;
  868.         test    di,1
  869.         jz      l1
  870.         stos    byte ptr Dst
  871.         dec     cx
  872. l1:
  873.         shr     cx,1
  874.         rep     stos word ptr Dst
  875.         adc     cl,cl
  876.         rep     stos byte ptr Dst
  877. else
  878. ;
  879. ;   This is the hard case, stos cant take a override, fake it
  880. ;
  881.         test    di,1
  882.         jz      l1
  883.         mov     byte ptr Dst,al
  884.         inc     di
  885.         dec     cx
  886. l1:     jcxz    l3
  887.         shr     cx,1
  888.         pushf
  889. l2:     mov     word ptr Dst,ax
  890.         inc     di
  891.         inc     di
  892.         loop    l2
  893.  
  894.         popf
  895.         jnc     l3
  896.         mov     byte ptr Dst,al
  897.         inc     di
  898. l3:
  899. endif
  900.         endm
  901.  
  902. REPSTOSB macro Dst
  903. ifb <Dst>
  904.         ?REPSTOSB es:[di]
  905. else
  906.         ?REPSTOSB Dst
  907. endif
  908.         endm
  909.  
  910. ;-------------------------Macro-----------------------------------------;
  911. ; REPMOVSB Dst, Src, alignR
  912. ;
  913. ; copy <cx> bytes from Src to Dst, aliging destination or source
  914. ; on WORD writes
  915. ;
  916. ;   Dst         destination, must be of the form SEL:[di] (default is es:[di])
  917. ;   Src         source,      must be of the form SEL:[si] (default is ds:[si])
  918. ;   alignR      register to align   si or di (default is di)
  919. ;
  920. ; Entry:
  921. ;   Src         -> points to source buffer
  922. ;   Dst         -> points to dest buffer
  923. ;   cx          count bytes
  924. ;
  925. ; NOTE a dest segment other than ES is handled by generating a loop
  926. ; all other cases generate a rep mov
  927. ;
  928. ; NOTE this code assumes the direction flag is set to FORWARD
  929. ;
  930. ; Returns:
  931. ;
  932. ; History:
  933. ;       Sun 31-Jul-1989  -by-  ToddLa
  934. ;    Wrote it.
  935. ;
  936. ;-----------------------------------------------------------------------;
  937.  
  938. ?REPMOVSB  macro Dst, Src, alignR
  939.         local   l1
  940.         local   l2
  941.         local   l3
  942.  
  943. fesdi = 0
  944.  
  945. ifidni <Dst>,<es:[di]>
  946.     fesdi = 1
  947. endif
  948.  
  949. ifidni <Dst>,<es:[edi]>
  950.     fesdi = 1
  951. endif
  952.  
  953. if fesdi
  954.         ;
  955.         ;   Destination segment register is ES we can use MOVS
  956.         ;
  957.         test    alignR,1
  958.         jz      l1
  959.         movs    byte ptr Dst, byte ptr Src
  960.         dec     cx
  961. l1:     shr     cx,1
  962.         rep     movs    word ptr Dst, word ptr Src
  963.         adc     cl,cl
  964.         rep     movs    byte ptr Dst, byte ptr Src
  965. else
  966.         ;
  967.         ;   Destination segment register is not ES!
  968.         ;   generate code that does the same thing
  969.         ;
  970.         push    ax
  971.  
  972.         test    alignR,1
  973.         jz      l1
  974.         lods    byte ptr Src
  975.         mov     byte ptr Dst,al
  976.         inc     di
  977.         dec     cx
  978. l1:     jcxz    l3
  979.         shr     cx,1
  980.         pushf
  981. l2:     lods    word ptr Src
  982.         mov     word ptr Dst,ax
  983.         inc     di
  984.         inc     di
  985.         loop    l2
  986.         popf
  987.         jnc     l3
  988.         lods    byte ptr Src
  989.         mov     byte ptr Dst,al
  990.         inc     di
  991. l3:
  992.         pop     ax
  993. endif
  994.         endm
  995.  
  996. REPMOVSB  macro Dst, Src, alignR
  997.  
  998. ifb <Dst>
  999.         ?REPMOVSB es:[di],ds:[si],di
  1000.         exitm
  1001. endif
  1002.  
  1003. ifb <Src>
  1004.         ?REPMOVSB Dst,ds:[si],di
  1005.         exitm
  1006. endif
  1007.  
  1008. ifb <alignR>
  1009.         ?REPMOVSB Dst,Src,di
  1010.         exitm
  1011. endif
  1012.         ?REPMOVSB Dst,Src,alignR
  1013.  
  1014.         endm
  1015.